package com.ihr360.payroll.controller.salarytask;

import com.ihr360.commons.request.Ihr360SearchBody;
import com.ihr360.entity.ApplicationApprovalEntity;
import com.ihr360.maven.plugin.ModuleCodeStore;
import com.ihr360.maven.plugin.annotation.FunctionDefinition;
import com.ihr360.maven.plugin.annotation.ModuleDefinition;
import com.ihr360.payroll.controller.salarytask.validator.PayPeriodEntityValidator;
import com.ihr360.payroll.entity.task.PayPeriodEntity;
import com.ihr360.payroll.entity.task.PayPeriodTermEntity;
import com.ihr360.payroll.model.vo.SalaryDataEntity;
import com.ihr360.payroll.model.vo.SalaryFieldEntity;
import com.ihr360.payroll.request.ApplicationIdRequest;
import com.ihr360.payroll.response.PayrollApprovalListResponse;
import com.ihr360.payroll.service.salarytask.SalaryTaskService;
import com.ihr360.payroll.type.PeriodState;
import com.ihr360.shared.advice.response.DisableResponseAdvice;
import com.ihr360.shared.basicstaffinfo.dto.SyncedBasicStaffInfo;
import com.ihr360.tasklet.JobExecutionOverview;
import com.ihr360.validation.annonation.EnableValidation;
import com.ihr360.validation.annonation.Valid;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 * 薪资任务相关接口
 */
@Api(value = "薪资任务相关接口")
@RestController
@RequestMapping("/salary/tasks")
@ModuleDefinition(mainModuleCode = ModuleCodeStore.Module.SALARY_CODE,
        mainModuleName = ModuleCodeStore.Module.SALARY_NAME,
        subModuleCode = ModuleCodeStore.Module.Salary.SALARY_TASK_CODE,
        subModuleName = ModuleCodeStore.Module.Salary.SALARY_TASK_NAME)
public class SalaryTaskController {
    @Autowired
    SalaryTaskService salaryTaskService;

    @FunctionDefinition(functionName = "获取薪资台账列表", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "获取薪资核算列表")
    @GetMapping(value = "/periods/list")
    public List<PayPeriodEntity> list(@RequestParam String companyId) {
        return salaryTaskService.getPayPeriods(companyId);
    }

    @FunctionDefinition(functionName = "获取账期批次数据", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "获取账期批次数据")
    @GetMapping(value = "/periods/term/{id}")
    public PayPeriodTermEntity getPayPeriodTerm(@PathVariable(name = "id") Long termId) {
        return salaryTaskService.getPayPeriodTerm(termId);
    }

    @FunctionDefinition(functionName = "获取具体薪资台账数据", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "获取账期信息")
    @GetMapping(value = "/periods/{id}")
    public PayPeriodEntity getOne(@PathVariable(name = "id") Long payPeriodId) {
        return salaryTaskService.getPayPeriod(payPeriodId);
    }

    @FunctionDefinition(functionName = "获取一个新的薪资台账数据快照", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "获取新的账期信息")
    @GetMapping(value = "/periods/new/{id}")
    public PayPeriodEntity getNewOne(@RequestParam String companyId, @PathVariable(name = "id") Long planId) {
        return salaryTaskService.getNewPayPeriod(companyId, planId);
    }

    @FunctionDefinition(functionName = "保存薪资台账数据", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "设置薪资核算方案的账期信息")
    @PostMapping(value = "/periods/setup")
    @EnableValidation
    public PayPeriodEntity setupPayPeriod(@RequestBody @Valid(validator = PayPeriodEntityValidator.class) PayPeriodEntity payPeriod) {
        return salaryTaskService.setupPayPeriod(payPeriod.getId(),payPeriod);
    }

    @FunctionDefinition(functionName = "撤销已开启的薪资台账", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "撤销（删除）账期数据")
    @PostMapping(value = "/periods/revoke/{id}")
    public boolean revoke(@PathVariable(name = "id") Long payPeriodId) {
        salaryTaskService.revoke(payPeriodId);
        return true;
    }

    @FunctionDefinition(functionName = "薪资台账添加员工", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "给账期中的添加员工")
    @PostMapping(value = "/periods/addStaff/{id}")
    public boolean addStaffSalary(@PathVariable(name = "id") Long payPeriodId, @RequestBody List<String> staffIdList) {
        salaryTaskService.addStaff2PayPeriod(payPeriodId, staffIdList);
        return true;
    }

    @FunctionDefinition(functionName = "薪资台账删除员工", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "从账期中的删除员工")
    @PostMapping(value = "/periods/deleteStaff/{id}")
    public boolean deleteStaffSalary(@PathVariable(name = "id") Long payPeriodId, @RequestBody List<String> staffIdList) {
        salaryTaskService.deleteStaff2PayPeriod(payPeriodId, staffIdList);
        return true;
    }

    @FunctionDefinition(functionName = "更新账期中的全部员工数据", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "更新账期中的全部员工数据")
    @PostMapping(value = "/periods/launchData/{id}")
    public JobExecutionOverview launchData(@PathVariable(name = "id") Long payPeriodId) {
        return salaryTaskService.launchData(payPeriodId);
    }

    @FunctionDefinition(functionName = "首次核算薪资台账", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "首次核算账期中的全部员工数据")
    @PostMapping(value = "/periods/firstCalculate/{id}")
    public JobExecutionOverview firstCalculate(@PathVariable(name = "id") Long payPeriodId) {
        return salaryTaskService.launchData(payPeriodId);
    }

    @FunctionDefinition(functionName = "重新核算薪资台账", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "重新核算账期中的全部/部分员工数据")
    @PostMapping(value = "/periods/reCalculate/{id}")
    public JobExecutionOverview reCalculate(@PathVariable(name = "id") Long payPeriodId,
                                            @RequestParam(required = false) List<String> staffIdList,
                                            @RequestParam boolean reloadData) {
        return salaryTaskService.reCalculate(payPeriodId, staffIdList, reloadData);
    }

    @FunctionDefinition(functionName = "获取账期表头信息", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "获取账期表头信息")
    @GetMapping(value = "/periods/header/{id}")
    public Map<String, SalaryFieldEntity> getPayPeriodStaffHeaderMap(@PathVariable(name = "id") Long payPeriodId) {
        return salaryTaskService.getPayPeriodHeaderMap(payPeriodId);
    }


    @FunctionDefinition(functionName = "获取账期数据", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "获取账期数据")
    @PostMapping(value = "/periods/data/{id}")
    public Page<SalaryDataEntity> getPayPeriodStaffDataCells(@RequestParam String companyId,
                                                             @PathVariable(name = "id") Long payPeriodId,
                                                             @RequestBody Ihr360SearchBody<SyncedBasicStaffInfo> searchBody) {
        return salaryTaskService.getPayPeriodStaffDataCells(companyId, payPeriodId, searchBody);
    }

    @FunctionDefinition(functionName = "保存修改薪资台账的员工数据", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "保存修改的账期数据")
    @PostMapping(value = "/periods/data/save")
    public boolean savePayPeriodSalaryData(@RequestParam Long termId, @RequestBody List<SalaryDataEntity> salaryDataEntities) {
        salaryTaskService.savePayPeriodSalaryData(termId, salaryDataEntities);
        return true;
    }

    /**
     * 根据审批applicationId查询账期信息
     */
    @FunctionDefinition(functionName = "根据审批applicationId查询账期信息", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "根据审批applicationId查询账期信息")
    @PostMapping(value = "/periods/approval/list")
    @DisableResponseAdvice
    public PayrollApprovalListResponse queryApprovalPayPeriod(@RequestBody ApplicationIdRequest request) {
        PayrollApprovalListResponse response = new PayrollApprovalListResponse();
        response.setPayrollApprovalResponseList(salaryTaskService.queryApprovalPayPeriod(request.getCompanyId(), request.getApplicationIdList()));
        return response;
    }

    /**
     * 提请审批保存审批id，状态
     */
    @FunctionDefinition(functionName = "提请审批保存审批id", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "提请审批保存审批id，状态")
    @PostMapping(value = "/periods/submit/approval")
    public void saveApprovalApplicationId(@RequestParam String companyId, @RequestBody ApplicationApprovalEntity applicationApprovalEntity, @RequestParam Long id) {
        salaryTaskService.saveApprovalApplicationId(companyId, applicationApprovalEntity, id);
    }

    /**
     * 审批同步修改账期状态
     */
    @FunctionDefinition(functionName = "审批同步修改账期状态", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "审批同步修改账期状态")
    @GetMapping(value = "/periods/approval/state")
    public void updateApprovalState(@RequestParam String companyId, @RequestParam String applicationId, @RequestParam PeriodState state) {
        salaryTaskService.updateApprovalState(companyId, applicationId, state);
    }

    /**
     * 薪酬账期关账
     */
    @FunctionDefinition(functionName = "薪酬账期关账", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "薪酬账期关账")
    @GetMapping(value = "/periods/close")
    public void closeActivePeriod(@RequestParam String companyId,@RequestParam Long id) {
        salaryTaskService.closeActivePeriod(id, companyId);
    }

}